<!DOCTYPE html>
<html lang=zh-CN>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta property="og:description" content="samuel-24276的博客">
    <meta property="og:type" content="website">
    <meta name="description" content="samuel-24276的博客">
    <meta name="keyword"  content="aircloud">
    <link rel="shortcut icon" href="/myblog/img/favicon.ico">

    <title>
        
        lambda 函数 - samuel-24276的博客 | samuel-24276&#39;s Blog
        
    </title>

    <!-- Custom CSS -->
    
<link rel="stylesheet" href="/myblog/css/aircloud.css">

    
<link rel="stylesheet" href="/myblog/css/gitment.css">

    <!--<link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css">-->
    <link href="//at.alicdn.com/t/font_620856_28hi1hpxx24.css" rel="stylesheet" type="text/css">
    <!-- ga & ba script hoook -->
    <script></script>
<meta name="generator" content="Hexo 7.1.1"></head>

<body>

<div class="site-nav-toggle" id="site-nav-toggle">
    <button>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
        <span class="btn-bar"></span>
    </button>
</div>

<div class="index-about">
    <i> Like what you do, do what you like </i>
</div>

<div class="index-container">
    
    <div class="index-left">
        
<div class="nav" id="nav">
    <div class="avatar-name">
        <div class="avatar ">
            <img src="/myblog/img/avatar.jpg" />
        </div>
        <div class="name">
            <i>samuel-24276</i>
        </div>
    </div>
    <div class="contents" id="nav-content">
        <ul>
            <li >
                <a href="/myblog/">
                    <i class="iconfont icon-shouye1"></i>
                    <span>主页</span>
                </a>
            </li>
            <li >
                <a href="/myblog/tags">
                    <i class="iconfont icon-biaoqian1"></i>
                    <span>标签</span>
                </a>
            </li>
            <li >
                <a href="/myblog/archives">
                    <i class="iconfont icon-guidang2"></i>
                    <span>存档</span>
                </a>
            </li>
            <li >
                <a href="/myblog/collect/">
                    <i class="iconfont icon-shoucang1"></i>
                    <span>收藏</span>
                </a>
            </li>
            <li >
                <a href="/myblog/about/">
                    <i class="iconfont icon-guanyu2"></i>
                    <span>关于</span>
                </a>
            </li>
            
            <li>
                <a id="search">
                    <i class="iconfont icon-sousuo1"></i>
                    <span>搜索</span>
                </a>
            </li>
            
        </ul>
    </div>
    
        <div id="toc" class="toc-article">
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%A6%82%E8%BF%B0"><span class="toc-text">概述</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#lambda-%E5%87%BD%E6%95%B0%E5%AE%9A%E4%B9%89"><span class="toc-text">lambda 函数定义</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%AF%AD%E6%B3%95%E5%AE%9A%E4%B9%89"><span class="toc-text">语法定义</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8D%95%E8%8E%B7%E5%88%97%E8%A1%A8"><span class="toc-text">捕获列表</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%82%E6%95%B0%E5%88%97%E8%A1%A8"><span class="toc-text">参数列表</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%AF%E5%8F%98%E8%A7%84%E6%A0%BCmutable"><span class="toc-text">可变规格mutable</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B"><span class="toc-text">返回类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E4%BD%93"><span class="toc-text">函数体</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86"><span class="toc-text">工作原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#std-function%E9%80%9A%E7%94%A8%E4%BB%BF%E5%87%BD%E6%95%B0Functor"><span class="toc-text">std::function通用仿函数Functor</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%92%8Cstd-function%E7%9A%84%E5%BC%82%E5%90%8C"><span class="toc-text">和std::function的异同</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF"><span class="toc-text">适用场景</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%86%85%E5%AE%B9%E5%B0%91%E4%B8%8D%E9%9C%80%E8%A6%81%E5%A4%8D%E7%94%A8%E7%9A%84%E5%87%BD%E6%95%B0"><span class="toc-text">内容少不需要复用的函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#STL%E7%AE%97%E6%B3%95"><span class="toc-text">STL算法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E4%B8%BAHash%E5%87%BD%E6%95%B0%EF%BC%8C%E6%8E%92%E5%BA%8F%E5%87%86%E5%88%99%E6%88%96%E7%9B%B8%E7%AD%89%E5%87%86%E5%88%99"><span class="toc-text">作为Hash函数，排序准则或相等准则</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%A8%E4%BA%8E%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%9C%BA%E6%99%AF"><span class="toc-text">用于多线程场景</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%A8%E4%BA%8E%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E4%B8%8Estd-function"><span class="toc-text">用于函数指针与std::function</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E5%85%A5%E5%8F%82%EF%BC%8C%E5%8F%AF%E7%94%A8%E4%BA%8E%E5%9B%9E%E8%B0%83"><span class="toc-text">作为函数入参，可用于回调</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E4%B8%BAQt%E7%9A%84%E6%A7%BD%E5%87%BD%E6%95%B0"><span class="toc-text">作为Qt的槽函数</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%92%8C%E4%B9%8B%E5%89%8D%E5%86%85%E5%AE%B9%E7%9A%84%E8%81%94%E7%B3%BB"><span class="toc-text">和之前内容的联系</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#lambda-vs-Binder"><span class="toc-text">lambda  vs. Binder</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#lambda-vs-%E5%B8%A6%E6%9C%89%E7%8A%B6%E6%80%81%E7%9A%84-stateful-Function-Object"><span class="toc-text">lambda  vs. 带有状态的(stateful) Function Object</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#lambda-%E8%B0%83%E7%94%A8%E5%85%A8%E5%B1%80%E5%87%BD%E6%95%B0%E5%92%8C%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0"><span class="toc-text">lambda 调用全局函数和成员函数</span></a></li></ol></li></ol>
</div>
    
</div>


<div class="search-field" id="search-field">
    <div class="search-bg" id="search-bg"></div>
    <div class="search-container">
        <div class="search-input">
            <span id="esc-search"> <i class="icon-fanhui iconfont"></i></span>
            <input id="search-input"/>
            <span id="begin-search">搜索</span>
        </div>
        <div class="search-result-container" id="search-result-container">

        </div>
    </div>
</div>

        <div class="index-about-mobile">
            <i> Like what you do, do what you like </i>
        </div>
    </div>
    
    <div class="index-middle">
        <!-- Main Content -->
        


<div class="post-container">
    <div class="post-title">
        lambda 函数
    </div>

    <div class="post-meta">
        <span class="attr">发布于：<span>2022-03-16 10:09:38</span></span>
        
        <span class="attr">标签：/
        
        <a class="tag" href="/myblog/tags/#C++" title="C++">C++</a>
        <span>/</span>
        
        
        </span>
        <span class="attr">访问：<span id="busuanzi_value_page_pv"></span>
</span>
</span>
    </div>
    <div class="post-content no-indent">
        <h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><p>​lambda 表达式引入始自C++11，是现代C++在C++11和更高版本中的一个新的语法糖 ，在C++11、C++14、C++17和C++20中 lambda 表达的内容还在不断更新。 lambda 表达式（也称为 lambda 函数）是在调用或作为函数参数传递的位置处定义<strong>匿名函数对象</strong>的便捷方法。就是当你想要将特定行为传给算法时，只要在需要的地方像指明函数那样把它写出来即可。</p>
<p>语法糖(Syntactic Sugar)是编程中的一个概念，指的是一种在语法上更简洁、更易读、更易书写，但<strong>实际上并没有引入新的功能或特性的语法结构</strong>。它们不会改变语言的功能，只是<strong>使代码更具可读性和易用性。语法糖可以让代码更清晰，更接近人类语言，减少了开发者的负担</strong>。</p>
<h1 id="lambda-函数定义"><a href="#lambda-函数定义" class="headerlink" title="lambda 函数定义"></a>lambda 函数定义</h1><h2 id="语法定义"><a href="#语法定义" class="headerlink" title="语法定义"></a>语法定义</h2><figure class="highlight scss"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-attr">[捕获列表]</span> <span class="selector-attr">[参数列表]</span> <span class="selector-attr">[可变规则]</span> <span class="selector-attr">[返回类型]</span> <span class="selector-attr">[函数体]</span></span><br><span class="line"><span class="selector-attr">[capture list]</span>(params) mutable -&gt;return-type &#123;&#125;</span><br></pre></td></tr></table></figure>
<h2 id="捕获列表"><a href="#捕获列表" class="headerlink" title="捕获列表"></a>捕获列表</h2><p>在C++规范中称为 lambda 导入器，[]是 lambda 引出符。编译器根据该引出符判断接下来的代码是否是 lambda 函数，捕获列表能够捕获上下文中变量以供 lambda 使用。</p>
<ul>
<li>[]表示不捕获任何变量<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> func1 = ([]&#123;</span><br><span class="line">		std::cout &lt;&lt; <span class="string">&quot;Hello World!&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">	&#125;</span><br><span class="line">);</span><br><span class="line"><span class="built_in">func1</span>();</span><br></pre></td></tr></table></figure></li>
<li>[var]表示以值传递方式捕获变量var<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">std::string name = <span class="string">&quot;Tom&quot;</span>;</span><br><span class="line"><span class="keyword">auto</span> func2 = ([name]&#123;</span><br><span class="line">		std::cout &lt;&lt; <span class="string">&quot;Hello &quot;</span> &lt;&lt; name &lt;&lt; std::endl;</span><br><span class="line">	&#125;</span><br><span class="line">);</span><br><span class="line"><span class="built_in">func2</span>();</span><br></pre></td></tr></table></figure></li>
<li>[&#x3D;]表示以值传递方式捕获父作用域的变量，包括this指针<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    ...</span><br><span class="line">    std::string name = <span class="string">&quot;Tom&quot;</span>;</span><br><span class="line">    <span class="keyword">auto</span> func3 = ([=]&#123;</span><br><span class="line">            std::cout &lt;&lt; <span class="string">&quot;Hello &quot;</span> &lt;&lt; name &lt;&lt; std::endl;</span><br><span class="line">        &#125;</span><br><span class="line">    );</span><br><span class="line">    <span class="built_in">func3</span>();</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li>[&amp;var]表示以引用传递方式捕获变量var，可以修改捕获的变量<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">std::string name = <span class="string">&quot;Tom&quot;</span>;</span><br><span class="line"><span class="keyword">auto</span> func4 = ([&amp;name]&#123;</span><br><span class="line">        name = <span class="string">&quot;Jerry&quot;</span>;</span><br><span class="line">		std::cout &lt;&lt; <span class="string">&quot;Hello &quot;</span> &lt;&lt; name &lt;&lt; std::endl;</span><br><span class="line">	&#125;</span><br><span class="line">);</span><br><span class="line"><span class="built_in">func4</span>();</span><br></pre></td></tr></table></figure></li>
<li>[&amp;]表示以引用传递方式捕获父作用域的变量，包括this指针，可以修改捕获的变量<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">std::string name = <span class="string">&quot;Tom&quot;</span>;</span><br><span class="line"><span class="keyword">auto</span> func5 = ([&amp;]&#123;</span><br><span class="line">        name = <span class="string">&quot;Jerry&quot;</span>;</span><br><span class="line">		std::cout &lt;&lt; <span class="string">&quot;Hello &quot;</span> &lt;&lt; name &lt;&lt; std::endl;</span><br><span class="line">	&#125;</span><br><span class="line">);</span><br><span class="line"><span class="built_in">func5</span>();</span><br></pre></td></tr></table></figure></li>
</ul>
<p>Note1:值传递时不需要考虑捕获变量的生命周期，但引用传递可能会涉及原有变量的修改，是需要考虑的，观察下方的代码：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// m_timer是该类的成员变量，下面的代码发生在该类的某个函数的最后流程</span></span><br><span class="line"><span class="type">int</span> cnt = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">connect</span>(&amp;m_timer, QTimer::timeout, <span class="keyword">this</span>, [&amp;cnt]&#123;</span><br><span class="line">    <span class="built_in">qDebug</span>() &lt;&lt; ++cnt;</span><br><span class="line">&#125;);</span><br><span class="line">m_timer.<span class="built_in">start</span>(<span class="number">1000</span>);</span><br></pre></td></tr></table></figure>
<p>每过一秒钟，打印一次cnt的值，最终的结果会递增吗？不会的，因为cnt是函数内的临时变量，当m_timer的超时触发 lambda 函数时，cnt临时变量已经析构，引用传递临时变量是无法修改其值的。** lambda 函数以引用传递方式捕获变量时，一定要考虑变量的生命周期！**</p>
<p>Note2:在 lambda 函数内使用智能指针，若 lambda 函数因某些原因没有结束生命周期，则智能指针指向的内存不会被销毁。 lambda  函数的生命周期取决于其所在的上下文，也即其作用域。常见的情况如下：</p>
<ul>
<li>在函数内部定义的 lambda 函数，其生命周期与函数的生命周期相同。</li>
<li>在类成员函数内部定义的 lambda 函数，其生命周期与类成员函数的生命周期相同。</li>
<li>在 lambda 函数中捕获外部变量的 lambda 函数，其生命周期会延长到外部变量的生命周期结束。</li>
</ul>
<p>以下情况可能导致 lambda 函数生命周期无法结束：</p>
<ul>
<li>循环引用: 如果 lambda 函数捕获了一个引用自身的变量，则会导致循环引用，从而阻止 lambda 函数的生命周期结束。</li>
<li>异常: 如果 lambda 函数内部抛出异常，并且没有被捕获，则会导致 lambda 函数的生命周期提前结束。</li>
<li>内存泄漏: 如果 lambda 函数内部使用了动态内存分配，并且没有在 lambda 函数结束时释放，则会导致内存泄漏。</li>
</ul>
<p>Note3：在 lambda 函数内以值&#x2F;引用传递方式捕获智能指针，则在 lambda 函数生命周期内使用智能指针时，其引用计数是增加的；若以引用传递方式捕获智能指针，但在 lambda 函数生命周期内使用的是其指向的裸指针，智能指针的引用计数不变。示例代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;memory&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    std::shared_ptr&lt;<span class="type">int</span>&gt; ptr = std::<span class="built_in">make_shared</span>&lt;<span class="type">int</span>&gt;(<span class="number">10</span>);</span><br><span class="line">    <span class="keyword">auto</span> ptrFunc1 = [ptr](<span class="type">int</span> a) &#123;</span><br><span class="line">        <span class="keyword">auto</span> p2 = ptr;<span class="comment">// 增加引用计数</span></span><br><span class="line">        std::cout &lt;&lt; *ptr &lt;&lt; <span class="string">&quot;,&quot;</span> &lt;&lt; ptr.<span class="built_in">use_count</span>()&lt;&lt; std::endl;</span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="built_in">ptrFunc1</span>(<span class="number">20</span>);</span><br><span class="line">    std::cout &lt;&lt; *ptr &lt;&lt; <span class="string">&quot;,&quot;</span> &lt;&lt; ptr.<span class="built_in">use_count</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="keyword">auto</span> p3 = ptr;<span class="comment">// 增加引用计数</span></span><br><span class="line">    std::cout &lt;&lt; *ptr &lt;&lt; <span class="string">&quot;,&quot;</span> &lt;&lt; ptr.<span class="built_in">use_count</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="keyword">auto</span> ptrFunc2 = [&amp;ptr]() &#123;</span><br><span class="line">        <span class="keyword">auto</span> p4 = &amp;ptr;</span><br><span class="line">        <span class="keyword">auto</span> p5 = ptr.<span class="built_in">get</span>();</span><br><span class="line">        std::cout &lt;&lt; *ptr &lt;&lt; <span class="string">&quot;,&quot;</span> &lt;&lt; ptr.<span class="built_in">use_count</span>()&lt;&lt; std::endl;</span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="built_in">ptrFunc2</span>();</span><br><span class="line">    std::cout &lt;&lt; *ptr &lt;&lt; <span class="string">&quot;,&quot;</span> &lt;&lt; ptr.<span class="built_in">use_count</span>() &lt;&lt; std::endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="参数列表"><a href="#参数列表" class="headerlink" title="参数列表"></a>参数列表</h2><p>除了捕获列表之外， lambda 还可以接受输入参数。参数列表是可选的，在大多数方面类似函数的参数列表。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> sum = [] (<span class="type">int</span> first, <span class="type">int</span> second)&#123;</span><br><span class="line">    <span class="keyword">return</span> first + second;</span><br><span class="line">&#125;;	</span><br><span class="line"><span class="built_in">sum</span>(<span class="number">100</span>, <span class="number">200</span>);</span><br></pre></td></tr></table></figure>

<p>Note: lambda 函数可以做Qt的槽函数，Qt的信号槽机制和boost的signal2库类似，本质上就是回调函数，但是速度不如回调函数，因为它们帮忙实现了线程安全，观察者模式和一些必要信息的存储。</p>
<h2 id="可变规格mutable"><a href="#可变规格mutable" class="headerlink" title="可变规格mutable"></a>可变规格mutable</h2><p>​mutable修饰符， 默认情况下 lambda 函数总是一个const函数，不可以对捕获列表的非引用传递的变量进行修改，mutable可以取消其常量性。在使用该修饰符时，参数列表不可省略（即使参数为空）。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">   <span class="type">int</span> m = <span class="number">0</span>;</span><br><span class="line">   <span class="type">int</span> n = <span class="number">0</span>;</span><br><span class="line">   <span class="comment">// 值传递捕获n，引用传递捕获n之外的变量m，mutable取消n的常量性，使其能够自增</span></span><br><span class="line">   [&amp;, n] (<span class="type">int</span> a) <span class="keyword">mutable</span> &#123; m = ++n + a; &#125;(<span class="number">4</span>);</span><br><span class="line">   cout &lt;&lt; m &lt;&lt; endl &lt;&lt; n &lt;&lt; endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="返回类型"><a href="#返回类型" class="headerlink" title="返回类型"></a>返回类型</h2><p>** lambda 函数的返回类型会自动推导**。除非你指定了返回类型，否则不必使用关键字。指定了返回类型，则返回类型必须在参数列表之后，并且必须在返回类型-&gt;之后包含类型关键字。如果 lambda 主体仅包含一个return语句或该函数未返回值，则可以省略 lambda 函数的return-type部分。如果 lambda 主体包含一个return语句，则编译器将从return函数的类型中推断出return类型。否则，编译器将返回类型推导为void。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">auto</span> cmp = [](<span class="type">int</span> a, <span class="type">int</span> b) -&gt; <span class="type">bool</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> a &gt; b;</span><br><span class="line">    &#125;;</span><br><span class="line">    <span class="keyword">auto</span> sort = [=](std::vector&lt;<span class="type">int</span>&gt;&amp; v) -&gt; <span class="type">void</span> &#123;</span><br><span class="line">        std::<span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), cmp);</span><br><span class="line">    &#125;;</span><br><span class="line">    std::vector&lt;<span class="type">int</span>&gt; intVec&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>&#125;;</span><br><span class="line">    <span class="built_in">sort</span>(intVec);</span><br><span class="line">    std::for_each(intVec.<span class="built_in">begin</span>(), intVec.<span class="built_in">end</span>(), [](<span class="type">int</span> i) &#123;</span><br><span class="line">        std::cout &lt;&lt; i &lt;&lt; std::endl;</span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="函数体"><a href="#函数体" class="headerlink" title="函数体"></a>函数体</h2><p>和普通函数一致，可以访问以下类型的变量：</p>
<ul>
<li>捕获变量</li>
<li>形参变量</li>
<li>局部声明的变量</li>
<li>类数据成员，当在类内声明**<code>this</code>**并被捕获时</li>
<li>具有静态存储持续时间的任何变量，例如全局变量</li>
</ul>
<h1 id="工作原理"><a href="#工作原理" class="headerlink" title="工作原理"></a>工作原理</h1><p>编译器会把一个lambda函数生成一个匿名类的匿名对象，并在类中重载函数调用运算符,实现了一个operator()方法。<code>auto print = []&#123;std::cout &lt;&lt; &quot;Hello World!&quot; &lt;&lt; std::endl; &#125;;</code>这个 lambda 函数会被编译器翻译为如下代码：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">print_class</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">	<span class="function"><span class="type">void</span> <span class="title">operator</span><span class="params">()</span><span class="params">(<span class="type">void</span>)</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">	</span>&#123;</span><br><span class="line">		std::cout &lt;&lt; <span class="string">&quot;Hello World！&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">auto</span> print = <span class="built_in">print_class</span>();<span class="comment">// print此时就是一个函数对象</span></span><br></pre></td></tr></table></figure>
<h2 id="std-function通用仿函数Functor"><a href="#std-function通用仿函数Functor" class="headerlink" title="std::function通用仿函数Functor"></a>std::function通用仿函数Functor</h2><p>仿函数（functor）又称为函数对象（function object）是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样，不过作为仿函数的类，都必须重载operator()运算符，仿函数与Lamdba函数的作用是一致的。示例代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Functor</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">operator</span><span class="params">()</span> <span class="params">(<span class="type">const</span> string&amp; str)</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        std::cout &lt;&lt; str &lt;&lt; std::endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Functor myFunctor;</span><br><span class="line">    <span class="built_in">myFunctor</span>(<span class="string">&quot;Hello world!&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="和std-function的异同"><a href="#和std-function的异同" class="headerlink" title="和std::function的异同"></a>和std::function的异同</h2><p>相同点:</p>
<ul>
<li>lambda  函数和 std::function 都是用来封装可调用对象的。</li>
<li>它们都可以用来存储和传递函数指针、函数对象和 lambda 函数。</li>
<li>它们都可以在运行时调用封装的可调用对象。</li>
</ul>
<p>不同点：</p>
<table>
<thead>
<tr>
<th>特性</th>
<th>lambda  函数</th>
<th>std::function</th>
</tr>
</thead>
<tbody><tr>
<td>语法</td>
<td>简洁</td>
<td>复杂</td>
</tr>
<tr>
<td>类型</td>
<td>匿名函数</td>
<td>类模板</td>
</tr>
<tr>
<td>捕获外部变量</td>
<td>可以</td>
<td>无法自动捕获</td>
</tr>
<tr>
<td>性能</td>
<td>较高</td>
<td>较低</td>
</tr>
<tr>
<td>通用性</td>
<td>较低</td>
<td>较高</td>
</tr>
</tbody></table>
<p>lambda 函数通用性较低，无法像std::function一样存储和传递任意可调用对象；而std::function性能较低，因为它需要进行动态内存分配（存储可调用对象）和类型擦除（确定可调用对象的类型）等工作。</p>
<h1 id="适用场景"><a href="#适用场景" class="headerlink" title="适用场景"></a>适用场景</h1><h2 id="内容少不需要复用的函数"><a href="#内容少不需要复用的函数" class="headerlink" title="内容少不需要复用的函数"></a>内容少不需要复用的函数</h2><h2 id="STL算法"><a href="#STL算法" class="headerlink" title="STL算法"></a>STL算法</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// for_each应用实例</span></span><br><span class="line"><span class="type">int</span> a[<span class="number">4</span>] = &#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">4</span>&#125;;</span><br><span class="line">std::<span class="built_in">sort</span>(a, a+<span class="number">4</span>, [=](<span class="type">int</span> x, <span class="type">int</span> y) -&gt; <span class="type">bool</span> &#123; <span class="keyword">return</span> x%<span class="number">10</span> &lt; y%<span class="number">10</span>; &#125; );</span><br><span class="line">std::for_each(a, a+<span class="number">4</span>, [=](<span class="type">int</span> x) &#123; cout &lt;&lt; x &lt;&lt; <span class="string">&quot; &quot;</span>;&#125; );</span><br></pre></td></tr></table></figure>

<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// find_if应用实例</span></span><br><span class="line"><span class="type">int</span> x = <span class="number">5</span>;</span><br><span class="line"><span class="type">int</span> y = <span class="number">10</span>;</span><br><span class="line">std::deque&lt;<span class="type">int</span>&gt; nums = &#123; <span class="number">1</span>, <span class="number">3</span>, <span class="number">19</span>, <span class="number">5</span>, <span class="number">13</span>, <span class="number">7</span>, <span class="number">11</span>, <span class="number">2</span>, <span class="number">17</span> &#125;;</span><br><span class="line"><span class="keyword">auto</span> pos = std::<span class="built_in">find_if</span>(nums.<span class="built_in">cbegin</span>(), nums.<span class="built_in">cend</span>(), [=](<span class="type">int</span> i) &#123;                 </span><br><span class="line">    <span class="keyword">return</span> i &gt; x &amp;&amp; i &lt; y;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// remove_if应用实例</span></span><br><span class="line">std::vector&lt;<span class="type">int</span>&gt; vec_data = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>&#125;;</span><br><span class="line"><span class="type">int</span> x = <span class="number">5</span>;</span><br><span class="line">vec_data.<span class="built_in">erase</span>(std::<span class="built_in">remove_if</span>(vec.date.<span class="built_in">begin</span>(), vec_data.<span class="built_in">end</span>(), [](<span class="type">int</span> i) &#123; </span><br><span class="line">    <span class="keyword">return</span> n &lt; x;&#125;</span><br><span class="line">), vec_data.<span class="built_in">end</span>());</span><br><span class="line"></span><br><span class="line">std::for_each(vec.date.<span class="built_in">begin</span>(), vec_data.<span class="built_in">end</span>(), [](<span class="type">int</span> i) &#123; </span><br><span class="line">    std::cout &lt;&lt; i &lt;&lt; std::endl;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="作为Hash函数，排序准则或相等准则"><a href="#作为Hash函数，排序准则或相等准则" class="headerlink" title="作为Hash函数，排序准则或相等准则"></a>作为Hash函数，排序准则或相等准则</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> cmp = [] (<span class="type">char</span> c1, <span class="type">char</span> c2)&#123;</span><br><span class="line">	<span class="keyword">return</span> c1&lt;c2;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">auto</span> hash = [](<span class="type">const</span> Person&amp; p)&#123;</span><br><span class="line">	...</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">auto</span> eq = [](<span class="type">const</span> Person&amp; p1, Person&amp; p2)&#123;</span><br><span class="line">	...</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function">unordered_set&lt;Person, <span class="title">decltype</span><span class="params">(hash)</span>, <span class="title">decltype</span><span class="params">(eq)</span>&gt; <span class="title">pset</span><span class="params">(<span class="number">10</span>, hash, eq)</span></span>;</span><br></pre></td></tr></table></figure>

<p>注意，你必须使用decltype将 lambda 的类型传给unordered_set，因为后者会建立属于它自己的一份实例。此外，你也必须传递一个hash函数和相等准则给构造函数，否则构造函数会调用hash函数和相等准则的default构造函数，而那对 lambda 而言是未定义的。<br>基于这些不方便性，在这里，针对function object给出一个class，也许可读性较高，甚至较便捷。所以<strong>当涉及状态(state)时， lambda 并非总是较好的选择</strong>。</p>
<h2 id="用于多线程场景"><a href="#用于多线程场景" class="headerlink" title="用于多线程场景"></a>用于多线程场景</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;thread&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">// vector 容器存储线程</span></span><br><span class="line">    std::vector&lt;std::thread&gt; workers;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++) </span><br><span class="line">    &#123;</span><br><span class="line">        workers.<span class="built_in">push_back</span>(std::<span class="built_in">thread</span>([]() </span><br><span class="line">        &#123;</span><br><span class="line">            std::cout &lt;&lt; <span class="string">&quot;thread function\n&quot;</span>;</span><br><span class="line">        &#125;));</span><br><span class="line">    &#125;</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;main thread\n&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 通过 for_each 循环每一个线程</span></span><br><span class="line">    <span class="comment">// 第三个参数赋值一个task任务</span></span><br><span class="line">    <span class="comment">// 符号&#x27;[]&#x27;会告诉编译器我们正在用一个匿名函数</span></span><br><span class="line">    <span class="comment">// lambda函数将它的参数作为线程的引用t</span></span><br><span class="line">    <span class="comment">// 然后一个一个的join</span></span><br><span class="line">    std::for_each(workers.<span class="built_in">begin</span>(), workers.<span class="built_in">end</span>(), [](std::thread &amp;t;) </span><br><span class="line">    &#123;</span><br><span class="line">        t.<span class="built_in">join</span>();</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">std::mutex mutex;</span><br><span class="line">std::condition_variable condition;</span><br><span class="line">std::queue&lt;std::string&gt; queue_data;</span><br><span class="line"></span><br><span class="line"><span class="function">std::thread <span class="title">threadBody</span><span class="params">([&amp;]&#123;</span></span></span><br><span class="line"><span class="params"><span class="function">	std::unique_lock&lt;std::mutex&gt; lock_log(mutex);</span></span></span><br><span class="line"><span class="params"><span class="function">	condition.wait(lock_log, [&amp;]&#123;</span></span></span><br><span class="line"><span class="params"><span class="function">		<span class="keyword">return</span> !queue_data.front();</span></span></span><br><span class="line"><span class="params"><span class="function">	&#125;);</span></span></span><br><span class="line"><span class="params"><span class="function">	std::cout &lt;&lt; <span class="string">&quot;queue data: &quot;</span> &lt;&lt; queue_data.front();</span></span></span><br><span class="line"><span class="params"><span class="function">	lock_log.unlock();</span></span></span><br><span class="line"><span class="params"><span class="function">&#125;)</span></span>;</span><br><span class="line"></span><br><span class="line">queue_data.<span class="built_in">push</span>(<span class="string">&quot;this is my data&quot;</span>);</span><br><span class="line">condition.<span class="built_in">notity_one</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(threadBody.<span class="built_in">joinable</span>())</span><br><span class="line">&#123;</span><br><span class="line">	threadBody.<span class="built_in">join</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="用于函数指针与std-function"><a href="#用于函数指针与std-function" class="headerlink" title="用于函数指针与std::function"></a>用于函数指针与std::function</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;functional&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> x = <span class="number">8</span>, y = <span class="number">9</span>;</span><br><span class="line">    <span class="keyword">auto</span> add = [](<span class="type">int</span> a, <span class="type">int</span> b) &#123; <span class="keyword">return</span> a + b; &#125;;</span><br><span class="line">    std::function&lt;<span class="type">int</span>(<span class="type">int</span>, <span class="type">int</span>)&gt; Add = [=](<span class="type">int</span> a, <span class="type">int</span> b) &#123; <span class="keyword">return</span> a + b; &#125;;</span><br><span class="line"></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;add: &quot;</span> &lt;&lt; <span class="built_in">add</span>(x, y) &lt;&lt; std::endl;</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Add: &quot;</span> &lt;&lt; <span class="built_in">Add</span>(x, y) &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="作为函数入参，可用于回调"><a href="#作为函数入参，可用于回调" class="headerlink" title="作为函数入参，可用于回调"></a>作为函数入参，可用于回调</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> FuncCallback = std::function&lt;<span class="built_in">void</span>(<span class="type">void</span>)&gt;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">DataCallback</span><span class="params">(FuncCallback callback)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	std::cout &lt;&lt; <span class="string">&quot;Start FuncCallback!&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">	<span class="built_in">callback</span>();</span><br><span class="line">	std::cout &lt;&lt; <span class="string">&quot;End FuncCallback!&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">auto</span> callback_handler = [&amp;]()&#123;</span><br><span class="line">	std::cout &lt;&lt; <span class="string">&quot;This is callback_handler&quot;</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="built_in">DataCallback</span>(callback_handler);</span><br></pre></td></tr></table></figure>
<h2 id="作为Qt的槽函数"><a href="#作为Qt的槽函数" class="headerlink" title="作为Qt的槽函数"></a>作为Qt的槽函数</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">QTimer *timer=<span class="keyword">new</span> QTimer;</span><br><span class="line">timer-&gt;<span class="built_in">start</span>(<span class="number">1000</span>);</span><br><span class="line">QObject::<span class="built_in">connect</span>(timer,&amp;QTimer::timeout,[&amp;]()&#123;</span><br><span class="line">        <span class="built_in">qDebug</span>() &lt;&lt; <span class="string">&quot;Lambda函数&quot;</span>;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h1 id="和之前内容的联系"><a href="#和之前内容的联系" class="headerlink" title="和之前内容的联系"></a>和之前内容的联系</h1><p><em>和《函数对象与函数适配器Binder》对比看更容易理解</em>。</p>
<h2 id="lambda-vs-Binder"><a href="#lambda-vs-Binder" class="headerlink" title="lambda  vs. Binder"></a>lambda  vs. Binder</h2><p>使用 lambda 改写 <em>2.1使用STL预定义函数对象时具体指定参数</em> 的例子，代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	<span class="keyword">auto</span> plus10 = [] (<span class="type">int</span> i) &#123;</span><br><span class="line">		<span class="keyword">return</span> i+<span class="number">10</span>;</span><br><span class="line">	&#125;;</span><br><span class="line">	cout&lt;&lt;<span class="string">&quot;+10:	&quot;</span>&lt;&lt;<span class="built_in">plus10</span>(<span class="number">7</span>)&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">auto</span> plus10times2 = [] (<span class="type">int</span> i) &#123;</span><br><span class="line">		<span class="built_in">return</span> (i+<span class="number">10</span>)*<span class="number">2</span>;</span><br><span class="line">	&#125;;</span><br><span class="line">	cout&lt;&lt;<span class="string">&quot;+10 * 2:	&quot;</span>&lt;&lt;<span class="built_in">plus10times2</span>(<span class="number">7</span>)&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">auto</span> pow3 = [] (<span class="type">int</span> i) &#123;</span><br><span class="line">		<span class="keyword">return</span> i*i*i;</span><br><span class="line">	&#125;;</span><br><span class="line">	cout&lt;&lt;<span class="string">&quot;x*x*x:	&quot;</span>&lt;&lt;<span class="built_in">pow3</span>(<span class="number">7</span>)&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">auto</span> inversDivide = [] (<span class="type">double</span> d1, <span class="type">double</span> d2) &#123;</span><br><span class="line">		<span class="keyword">return</span> d2/d1;</span><br><span class="line">	&#125;;</span><br><span class="line">	cout&lt;&lt;<span class="string">&quot;invdiv:	&quot;</span>&lt;&lt;<span class="built_in">inversDivide</span>(<span class="number">49</span>, <span class="number">7</span>)&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>对比发现， lambda 函数比函数对象的写法要简洁的多，看起来像函数一样，有名字，有参数，有行为，但它不是函数，是一种语言特性。</p>
<h2 id="lambda-vs-带有状态的-stateful-Function-Object"><a href="#lambda-vs-带有状态的-stateful-Function-Object" class="headerlink" title="lambda  vs. 带有状态的(stateful) Function Object"></a>lambda  vs. 带有状态的(stateful) Function Object</h2><p>我们使用 lambda 改写 <em>1.4.改变function object的内部状态（Internal State)</em> 中计算中值的函数（mean value），代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;vector&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	vector&lt;<span class="type">int</span>&gt; coll =&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>&#125;;</span><br><span class="line"></span><br><span class="line">	<span class="type">long</span> sum = <span class="number">0</span>;</span><br><span class="line">	for_each(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(),</span><br><span class="line">			[&amp;sum] (<span class="type">int</span> elem)&#123;</span><br><span class="line">				sum += elem;</span><br><span class="line">			&#125;);</span><br><span class="line">	<span class="type">double</span> mv = <span class="built_in">static_cast</span>&lt;<span class="type">double</span>&gt;(sum)/<span class="built_in">static_cast</span>&lt;<span class="type">double</span>&gt;(coll.<span class="built_in">size</span>());</span><br><span class="line">	cout&lt;&lt;<span class="string">&quot;mean value:&quot;</span>&lt;&lt;mv&lt;&lt;endl;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在Function Object中，sum和num都是内部的状态，被封装在类MeanValue中。而使用 lambda 则不需要另外定义类MeanValue存放内部状态sum和num，只需要定义变量sum，且要以引用方式传递给 lambda ，即[&amp;sum]，而num可以用coll.size()代替，简洁了许多。</p>
<p>处理状态时，使用mutable(可复制的，可改变的)需要格外小心。我们编写一个查找第三元素的查找准则，以by value方式传递内部计数器（内部状态），写上mutable你便可以对该状态提供write访问权，且适用于对它的所有函数调用。代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;list&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;print.hpp&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	list&lt;<span class="type">int</span>&gt; coll =&#123;<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>&#125;;</span><br><span class="line">	<span class="built_in">PRINT_ELEMENTS</span>(coll, <span class="string">&quot;coll:	&quot;</span>);</span><br><span class="line"></span><br><span class="line">	list&lt;<span class="type">int</span>&gt;::iterator pos;</span><br><span class="line">	<span class="type">int</span> count=<span class="number">0</span>;</span><br><span class="line">	pos = <span class="built_in">remove_if</span>(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(), </span><br><span class="line">					[count] (<span class="type">int</span>) <span class="keyword">mutable</span> &#123;</span><br><span class="line">						<span class="keyword">return</span> ++count == <span class="number">3</span>;</span><br><span class="line">					&#125;);</span><br><span class="line">	coll.<span class="built_in">erase</span>(pos, coll.<span class="built_in">end</span>());</span><br><span class="line"></span><br><span class="line">	<span class="built_in">PRINT_ELEMENTS</span>(coll, <span class="string">&quot;3rd removed:	&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>运行后发现输出少了3和6，之所以如此，因为 lambda 对象被remove_if()算法在执行中复制了一份，于是存在两个 lambda 对象都移除第三元素，导致重复的行为。<br>如果你以by reference方式传递实参，又未使用mutable，那么行为一如预期，因为remove_if()内部所用的两个 lambda 对象共享同一状态。代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line">pos = <span class="built_in">remove_if</span>(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(),</span><br><span class="line">				[&amp;count] (<span class="type">int</span>) &#123;</span><br><span class="line">					<span class="keyword">return</span> ++count == <span class="number">3</span>;</span><br><span class="line">				&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="lambda-调用全局函数和成员函数"><a href="#lambda-调用全局函数和成员函数" class="headerlink" title="lambda 调用全局函数和成员函数"></a>lambda 调用全局函数和成员函数</h2><p>我们改写 <em>2.2.调用全局函数</em> 的例子，代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;functional&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;locale&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">char</span> <span class="title">myToupper</span><span class="params">(<span class="type">char</span> c)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    std::locale loc;</span><br><span class="line">    <span class="keyword">return</span> std::use_facet&lt;std::ctype&lt;<span class="type">char</span>&gt;&gt;(loc).<span class="built_in">toupper</span>(c);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="function">string <span class="title">s</span><span class="params">(<span class="string">&quot;Internationalization&quot;</span>)</span></span>;</span><br><span class="line">    <span class="function">string <span class="title">sub</span><span class="params">(<span class="string">&quot;Nation&quot;</span>)</span></span>;</span><br><span class="line"></span><br><span class="line">    string::iterator pos;</span><br><span class="line">    pos = <span class="built_in">search</span>(s.<span class="built_in">begin</span>(), s.<span class="built_in">end</span>(), </span><br><span class="line">				sub.<span class="built_in">begin</span>(), sub.<span class="built_in">end</span>(), </span><br><span class="line">				[] (<span class="type">char</span> c1, <span class="type">char</span> c2) &#123;</span><br><span class="line">					<span class="keyword">return</span> <span class="built_in">myToupper</span>(c1) == <span class="built_in">myToupper</span>(c2);</span><br><span class="line">				&#125;);</span><br><span class="line">    <span class="keyword">if</span> (pos != s.<span class="built_in">end</span>())</span><br><span class="line">    &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;\&quot;&quot;</span> &lt;&lt; sub &lt;&lt; <span class="string">&quot;\&quot;is part of \&quot;&quot;</span> &lt;&lt; s &lt;&lt; <span class="string">&quot;\&quot;&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>对比发现，两者只有search()函数里的查找准则不同， lambda 的更简洁易懂，调用全局函数只要提供需要的参数即可。我们改写 <em>2.3.调用成员函数</em> 的例子，代码如下：</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;functional&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    string name;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">Person</span>(<span class="type">const</span> string&amp; n): <span class="built_in">name</span>(n)&#123;&#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">print</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        cout &lt;&lt; name &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">print2</span><span class="params">(<span class="type">const</span> string&amp; prefix)</span> <span class="type">const</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        cout &lt;&lt; prefix &lt;&lt; name &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    vector&lt;Person&gt; coll = &#123;<span class="built_in">Person</span>(<span class="string">&quot;Tick&quot;</span>), <span class="built_in">Person</span>(<span class="string">&quot;Trick&quot;</span>), <span class="built_in">Person</span>(<span class="string">&quot;Track&quot;</span>)&#125;;</span><br><span class="line"></span><br><span class="line">    for_each(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(),</span><br><span class="line">			[] (<span class="type">const</span> Person&amp; p) &#123;</span><br><span class="line">				p.<span class="built_in">print</span>();</span><br><span class="line">			&#125;);</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    for_each(coll.<span class="built_in">begin</span>(), coll.<span class="built_in">end</span>(),</span><br><span class="line">			[] (<span class="type">const</span> Person&amp; p) &#123;</span><br><span class="line">				p.<span class="built_in">print2</span>(<span class="string">&quot;Person:&quot;</span>);</span><br><span class="line">			&#125;);</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>对比发现，两者只有for_each()函数里的调用算法不同， lambda 写成的算法更简洁易懂，调用成员函数需要提供调用的对象名，若调用的成员函数为非更易型算法，还应该加上const。</p>
<hr>

        
            <div class="donate-container">
    <div class="donate-button">
        <button id="donate-button">赞赏</button>
    </div>
    <div class="donate-img-container hide" id="donate-img-container">
        <img id="donate-img" src="" data-src="/myblog/img/donate.jpg">
        <p> 感谢鼓励 </p>
    </div>
</div>
        
        <br />
        <div id="comment-container">
        </div>
        <div id="disqus_thread"></div>
        <div id="lv-container"></div>
        <div class="giscus"></div>
    </div>
</div>

    </div>
</div>


<footer class="footer">
    <ul class="list-inline text-center">
        
        

        

        

        
        <li>
            <a target="_blank"  href="https://github.com/samuel-24276">
                            <span class="fa-stack fa-lg">
                                <i class="iconfont icon-github"></i>
                            </span>
            </a>
        </li>
        

        

    </ul>
    
    <p>
        <span>/</span>
        
        <span><a target="_blank" rel="noopener" href="https://github.com/samuel-24276">samuel-24276&#39;s Page</a></span>
        <span>/</span>
        
        <span><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/">北京-未备案</a></span>
        <span>/</span>
        
        <span><a href="#">返回顶部</a></span>
        <span>/</span>
        
    </p>
    
    <p>
        <span id="busuanzi_container_site_pv">
            <span id="busuanzi_value_site_pv"></span>PV
        </span>
        <span id="busuanzi_container_site_uv">
            <span id="busuanzi_value_site_uv"></span>UV
        </span>
        Created By <a target="_blank" rel="noopener" href="https://hexo.io/">Hexo</a>  Theme <a target="_blank" rel="noopener" href="https://github.com/aircloud/hexo-theme-aircloud">AirCloud</a></p>
</footer>




</body>

<script>
    // We expose some of the variables needed by the front end
    window.hexo_search_path = "search.json"
    window.hexo_root = "/myblog/"
    window.isPost = true
</script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

<script src="/myblog/js/index.js"></script>

<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>






    <script type="text/javascript">
       (function() {
           if (typeof LivereTower === 'function') { return; }

           var j, d = document.getElementById('lv-container');

           d.setAttribute('data-id','city');
           d.setAttribute('data-uid' , 'MTAyMC80OTA5OC8yNTU5Mw==');

           j = document.createElement('script');
           j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
           j.async = true;

           d.appendChild(j);
       })();
    </script>
    <noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
    </div>

</html>
